require("Content")
require("Sentence")

Physical = class("Physical", Content)

---

function Physical:initialize(name, type)

	if not type 
	then
		type = "Physical"
	end
	
	Content.initialize(self, name, type)
	self:registerEntityType("Physical")
	
	
	self.properties["CurrentContainer"] = Location.Everywhere({"Room"})  -- , "Furniture"})
end  

---

function Physical:execute(parameter1, parameter2)

	if type(parameter1) == "string"
	then
		local sentence = Sentence:new()
		
		sentence:setSubject(self)
		sentence:setVerb(parameter1)
		sentence:setDirectObject(parameter2)	
		
		self:execute(sentence)	
	else
		local sentence = parameter1
		local sentenceSubject = sentence:getSubject()
		
		assert(
			(
				(sentenceSubject) and
				(sentenceSubject.name == self.name) and
				(sentenceSubject.type == self.type)
			),
			"Trying to execute a Sentence where the Physical is not the subject of the Sentence"		
		)
		
		local verb = sentence:getVerb()
		
		assert(
			(
				self[verb] and
				(type(self[verb]) == "function")
			),
			"Trying to execute a Sentence where the verb is not a function of the Physical"
		)
		
		self[verb](self, sentence)
	end
end

---

function Physical:sensePossibleActions()

	self.possibleActionDirectory = {}
	self.lockedActionDirectory = {}
	
	self:addMoveToActionsToDirectory()
end

---

function Physical:addPossibleActionToDirectory(sentence)

	local verb = sentence:getVerb()
	
	if not self.possibleActionDirectory[verb] 
	then
		self.possibleActionDirectory[verb] = {}
	end
	
	self.possibleActionDirectory[verb][#(self.possibleActionDirectory[verb]) + 1] = sentence
end

---

function Physical:addLockedActionToDirectory(sentence)

	local verb = sentence:getVerb()
	
	if not self.lockedActionDirectory[verb] 
	then
		self.lockedActionDirectory[verb] = {}
	end
	
	self.lockedActionDirectory[verb][#(self.lockedActionDirectory[verb]) + 1] = sentence
end

---

function Physical:addMoveToActionsToDirectory()

	local currentLocation = self:getCollapsedProperty("CurrentContainer")
	local doorsToNeighborhood = currentLocation.doorsToNeighborhood
	
	if next(doorsToNeighborhood) 
	then
		for dooName, doorEntity in pairs(doorsToNeighborhood) do
		
			local sentence = Sentence:new()
			
			sentence:setSubject(self)
			sentence:setVerb("moveTo")
			sentence:setDirectObject(doorEntity:getOtherSide(currentLocation))
			
			if doorEntity:isEnabled() 
			then
				self:addPossibleActionToDirectory(sentence)
			else
				self:addLockedActionToDirectory(sentence)
			end
		end
	end
end

	
--- Verbs

function Physical:moveTo(sentence)

	local destination = sentence:getDirectObject()
	
	self:collapseProperty("CurrentContainer", destination)
	
	gLogger:log(self.type .. " " .. self.name .. " moved to " .. destination.type .. " " .. destination.name)
end
